package com.easyexcel.demo.component;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easyexcel.demo.service.UserService;
import com.easyexcel.demo.util.EasyExcelUtil;
import com.easyexcel.demo.vo.UserQuery;
import com.easyexcel.demo.vo.UserVO;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;

/**
 * @author zhaoxh
 * @version : UserMultisheetComponent.java, v 0.1 2023/9/14 zhaoxh Exp $
 * @desc  多sheet页分批导出
 */
@Service
public class UserMultiSheetService {

    @Resource
    private UserService userService;

    private static final String EXPORT_FILE_NAME_TEMPLATE = "【%s】用户信息导出";
    private static final String EXPORT_SHEET_NAME_TEMPLATE = "用户信息";

    /**
     * 触发分批导出阈值
     */
    private static final Integer PART_EXPORT_NUM = 50;
    /**
     * 每个sheet页的最大数量触发了切换下一个sheet页 这个值必须大于分批的阈值且%阈值==0
     */
    private static final Integer PART_EXPORT_SHEET_NUM = 50;

    @SneakyThrows
    public void exportExcel(HttpServletRequest request, HttpServletResponse response, UserQuery query) {
        // 设置文件名
        String fileName = String.format(EXPORT_FILE_NAME_TEMPLATE, DateUtil.now());
        // 设置响应头
        EasyExcelUtil.setResponseHeaders(response, fileName);
        // 创建输出流
        ServletOutputStream outputStream = response.getOutputStream();
        // 创建excel对象
        ExcelWriter excelWriter = EasyExcelUtil.excelWriter(outputStream, UserVO.class);
        // 初始化分页参数
        query.setCurrent(1);
        query.setSize(PART_EXPORT_NUM);

        int sheetIndex = 0; // Sheet页索引
        int accumulatedRows = 0; // 累计行数计数器

        // 循环分页获取数据并写入Excel
        while (true) {
            Page<UserVO> pageResult = userService.page(query);
            List<UserVO> records = pageResult.getRecords();

            // 如果当前页无数据，结束导出
            if (records.isEmpty()) {
                break;
            }

            // 计算当前Sheet剩余可写行数
            int remainingInSheet = PART_EXPORT_SHEET_NUM - accumulatedRows;
            int writeCount = Math.min(records.size(), remainingInSheet);

            // 构建Sheet并写入数据
            WriteSheet writeSheet = EasyExcel.writerSheet("用户信息" + sheetIndex).build();
            excelWriter.write(records.subList(0, writeCount), writeSheet);

            // 更新累计行数和Sheet索引
            accumulatedRows += writeCount;
            if (accumulatedRows >= PART_EXPORT_SHEET_NUM) {
                sheetIndex++;
                accumulatedRows = 0;
            }

            // 移动到下一页
            query.setCurrent(query.getCurrent() + 1);
        }

        // 完成写入并关闭资源
        excelWriter.finish();
        outputStream.flush();
        outputStream.close();
    }
}
